﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class Player : MonoBehaviour
{
    public CharacterController Controller;//角色控制器
    public PlayerBase playerBases = new PlayerBase();
    GameObject p; //初始化后的角色
    private int LerpSpeed = 5;

    public string PlayerName= "QAQ";
    public int score = 0;

    

    #region 获取物体
    [Header("预制体")]
    /// <summary> 游戏角色对象的空物体 </summary>
    public Player playerCharacter;
    /// <summary> 角色模型 </summary>
    public static GameObject PlayerPrefab;
    /// <summary> 角色根对象 </summary>
    public GameObject root;
    /// <summary> 角色地面位置产生的物体 </summary>
    public List<GameObject> rootPrefabs;
    /// <summary> 子弹预制体 </summary>
    public GameObject bulletPrefab;
    /// <summary> 子弹生成位置 </summary>
    public Transform bulletPos;

    [Header("UI资源")]
    /// <summary> UI血条 </summary>
    public Slider lifbar;
    /// <summary> UI经验条 </summary>
    public Slider empiricalValue;
    /// <summary> UI等级显示 </summary>
    public Text lvlText;
    /// <summary> 死亡后特效 </summary>
    public GameObject DiedEffect;
    /// <summary> 选择菜单 </summary>
    public GameObject selectMenu;
    /// <summary> 音乐控制按键 </summary>
    public GameObject musicSet;

    [Header("音乐资源")]
    /// <summary> 死亡音乐 </summary>
    public AudioClip deadClip;
    /// <summary> 攻击音效 </summary>
    public AudioClip attackClip;
    /// <summary> 受击音效 </summary>
    public AudioClip beAttackClip;
    /// <summary> 拾取经验音效 </summary>
    public AudioClip expPickupClip;
    /// <summary> 拾取血球音效 </summary>
    public AudioClip bloodPickupClip;

    #endregion

    #region 角色数值初始化
    [Header("玩家属性")]
    /// <summary> 判断子弹射出的位置(true-脚部，false-手部) </summary>
    public bool rootShot = false;
    /// <summary> 子弹速度 </summary>
    public static float bulletSpeed = 10;
    /// <summary> 角色初始发射弹数 </summary>
    public int shotCount = 1;
    /// <summary> 角色初始等级 </summary>
    public int lvl = 1;
    /// <summary> 角色初始血量 </summary>
    public float hp = 10;
    /// <summary>角色血量上限 </summary>
    public float max_hp = 10;
    /// <summary> 角色初始攻击 </summary>
    public float atk = 2;
    /// <summary> 角色初始防御 </summary>
    public float def = 0;
    /// <summary> 角色初始射程 </summary>
    public float atkRange = 10;
    /// <summary> 角色初始移动速度 </summary>
    public float speed = 5;
    /// <summary> 角色初始拾取范围 </summary>
    public float pickUpRange = 0.7f;
    /// <summary> 角色初始经验值 </summary>
    public float exp = 1;
    /// <summary> 角色初始经验球吸收值 </summary>
    public float expBall_value = 1;
    /// <summary> 角色初始经验槽上限 </summary>
    public float max_exp = 10;
    #endregion

    /// <summary> 单例 </summary>
    private static Player _Instance;
    public static Player Insatance { get { return _Instance; } }
    void Awake()
    {
        if (GlobalMessage.PlayerName != null)
        {
            PlayerName = GlobalMessage.PlayerName;
        }
        
        if (_Instance != null)
        {
            Destroy(this.gameObject); return;
        }
        _Instance = this;

    }

    // Start is called before the first frame update
    void Start()
    {
        
        //角色模型初始化
        p = Instantiate(PlayerPrefab, playerCharacter.transform.GetChild(0));
        p.GetComponent<Animator>().enabled = true;
        #region 初始数值设定
        playerBases.shotCount = shotCount;
        playerBases.lvl = lvl;
        playerBases.hp = hp;
        playerBases.max_hp = max_hp;
        playerBases.atk = atk;
        playerBases.def = def;
        playerBases.atkRange = atkRange;
        playerBases.speed = speed;
        playerBases.pickUpRange = pickUpRange;
        playerBases.exp = exp;
        playerBases.expBall_value = expBall_value;
        playerBases.max_exp = max_exp;
        setPickUpRange(pickUpRange);
        rootShot = false;
        rootPrefabs.Clear();
        #endregion
    }

    // Update is called once per frame
    void Update()
    {
        //角色血条
        lifbar.transform.LookAt(GameObject.Find("Main Camera").transform);
        GlobalMessage.score = score;
        int temp = score / 10;
        GlobalMessage.kill = temp;
    }

    



    /// <summary> 受到攻击事件 </summary>
    /// <param name="damage"> 伤害值 </param>
    public void GetAttack(float damage)
    {
        if (hp < 0) return;//安全检测
        Vector3 temp =new Vector3(transform.position.x, transform.position.y, transform.position.z - 1);
        Vector3.Lerp(transform.position, temp, Time.deltaTime * LerpSpeed);
        this.GetComponent<AudioSource>().PlayOneShot(beAttackClip);//攻击音效
        hp -= (damage - def) > 0 ? (damage - def) : 0.1f;
        lifbar.value = hp / max_hp;//得到血量的百分比并给予血条显示

        if (hp < 0)
        {
            PlayerDied();
        }
    }

    /// <summary> 攻击事件 </summary>
    public void Attack()
    {
        //判断子弹生成位置
        Transform shotPlace;
        if (rootShot)
            shotPlace = root.transform;
        else
            shotPlace = bulletPos.transform;

        #region 子弹数量展开计算
        float angle;//子弹展开的总角度，随子弹数量增加

        if (shotCount == 1)
            angle = 0;//不偏移
        else
            angle = 10 * shotCount;//计算偏移角度

        float angleOffset = angle / shotCount;//子弹之间角度偏移
        Quaternion bulletRot;
        for (int i = 0; i < shotCount; i++)
        {
            bulletRot = shotPlace.rotation * Quaternion.Euler(0, angle / 2 - angleOffset * i, 0);
            GameObject b = Instantiate(bulletPrefab, shotPlace.position, bulletRot);//生成子弹
            b.GetComponent<Bullet>().atk = atk;
            b.GetComponent<Bullet>().CharCollider = gameObject.GetComponent<CharacterController>();
        }
        #endregion

        GetComponent<AudioSource>().PlayOneShot(attackClip);//攻击音效

        //todo: 生成爆炸特效
    }

    /// <summary> 获取经验/升级事件 </summary>
    public void getEmpirical()
    {
        score += 10;
        exp += expBall_value;
        GetComponent<AudioSource>().PlayOneShot(expPickupClip);
        empiricalValue.value = exp / max_exp;
        //升级逻辑
        if (empiricalValue.value >= 1)
        {
            empiricalValue.value = 0;
            exp -= max_exp;
            max_exp *= 1.2f;
            lvl++;
            lvlText.text = "Lv." + lvl;
            SkillManager._instance.gainSkill(gameObject);
        }
    }

    /// <summary> 设置拾取范围 </summary>
    public void setPickUpRange(float rangeValue)
    {
        transform.GetComponentInChildren<SphereCollider>().radius = rangeValue;
    }
    /// <summary> 人物死亡 </summary>
    public void PlayerDied()
    {
        speed = 0;
        selectMenu.gameObject.SetActive(true);
        musicSet.GetComponent<AudioSource>().Pause();//背景音乐控制
        GetComponent<AudioSource>().PlayOneShot(deadClip);//死亡音乐
        Destroy(gameObject.transform.GetChild(0).transform.GetChild(3).gameObject);//人物模型
        gameObject.transform.GetChild(2).gameObject.SetActive(false);//血条  
        p = Instantiate(DiedEffect, playerCharacter.transform.GetChild(0));//死亡特效
        //todo: 播放爆炸特效
    }

    public void Revive()
    {
        selectMenu.gameObject.SetActive(false);
        musicSet.GetComponent<AudioSource>().Play();//背景音乐控制
        speed = playerBases.speed;
        hp = playerBases.max_hp;
        lifbar.value = hp / max_hp;
        Destroy(p.gameObject);
        p = Instantiate(PlayerPrefab, playerCharacter.transform.GetChild(0));
        gameObject.transform.GetChild(2).gameObject.SetActive(true);//血条
    }

    /// <summary> 回血 </summary>
    public void PlusBlood()
    {
        hp += 2;
        lifbar.value = hp / max_hp;
        GetComponent<AudioSource>().PlayOneShot(bloodPickupClip);
    }

}
